<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        body{
            outline: lightblue solid;
        }
        output{
            padding: 1rem;
            font-size: 2rem;
            background: skyblue;
        }
    </style>
</head>
<body>
<div id="container">
    <output>0</output>
</div>
<script src="underscore-1.9.1.js"></script>
<script>
    onload = function () {
        let counter = 0;
        let output = document.querySelector('output');
        // document.querySelector('body').addEventListener('onmousemove',_.debounce(function () {
        document.querySelector('body').onmousemove = _.myDebounce(function () {
            output.innerText = counter+++'';
        },1500)
    };
    // underscore源码
    _.myDebounce = function(func, wait, immediate) {
        var timeout, result;

        var later = function(context, args) {
            timeout = null;
            if (args) result = func.apply(context, args);
        };

        var debounced = _.restArguments(function(args) {
            if (timeout) clearTimeout(timeout); // 清除超时调用后，函数不再执行，但变量timeout(是“number"类型)数值仍然不变。
            if (immediate) { // 如果为true则立即执行，后面不再执行，除非触发时间间隔达到要求，再次触发事件，然后又立即执行一次……
                var callNow = !timeout; // 等够了时间间隔，callNow即为true
                timeout = setTimeout(later, wait); // 因为给later没传参调用，所以later中仅将timeout置为null，第二步不会触发
                if (callNow) result = func.apply(this, args); // 回调函数的this用当前函数(_.debounce最终返回的函数)的this代替
            } else {
                timeout = _.delay(later, wait, this, args);
            }

            return result;
        });

        debounced.cancel = function() {
            clearTimeout(timeout);
            timeout = null;
        };

        return debounced;
    };
</script>
</body>
</html>